<template>
  <demo-content :title="title">
    <p>下面的橡皮筋框选就是通过隐藏 div 实现的。</p>
    <button style="margin-bottom: 10px" @click="reset">重置</button>
    <div ref="canvasContainer" style="position: relative">
      <div id="rubberbandDiv" :style="rubberbandStyle"></div>
      <canvas
        ref="canvasRef"
        width="800"
        height="520"
        style="cursor: crosshair"
      ></canvas>
    </div>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { clientPosCvt } from "./utils";
// image 为一个 string，被转换为值 /src/assets/arch.png
import imagePath from "@/assets/arch.png";
import { computed } from "vue";

const title = "不可见HTML元素";
// 指定组件上的属性
defineOptions({ title });

const canvasRef = ref<HTMLCanvasElement>();
const canvasContainer = ref<HTMLElement>();
const showRubberband = ref(false);
const startPos = ref({ x: 0, y: 0 });
const endPos = ref({ x: 0, y: 0 });
const rubberbandPos = computed(() => {
  const { x: x0, y: y0 } = startPos.value;
  const { x: x1, y: y1 } = endPos.value;
  return {
    left: Math.min(x0, x1),
    top: Math.min(y0, y1),
    width: Math.abs(x0 - x1),
    height: Math.abs(y0 - y1),
  };
});
const rubberbandStyle = computed(() => ({
  display: showRubberband.value ? "inline" : "none",
  left: `${rubberbandPos.value.left}px`,
  top: `${rubberbandPos.value.top}px`,
  width: `${rubberbandPos.value.width}px`,
  height: `${rubberbandPos.value.height}px`,
}));

const image = new Image();
let ctx: CanvasRenderingContext2D;

function reset() {
  ctx.drawImage(image, 0, 0);
}

onMounted(() => {
  const canvas = canvasRef.value!;
  ctx = canvas.getContext("2d")!;
  image.src = imagePath;
  image.onload = () => {
    reset();
  };
  canvas.onmousedown = (e) => {
    const { x, y } = clientPosCvt(ctx, e);
    startPos.value = { x, y };
    endPos.value = { ...startPos.value };
    showRubberband.value = true;
  };
  canvas.onmousemove = (e) => {
    if (!showRubberband.value) return;
    const { x, y } = clientPosCvt(ctx, e);
    endPos.value = { x, y };
  };
  // canvas.onmouseup = (_e) => {
  //   console.log("!!!!");
  //   showRubberband.value = false;
  // };
  canvasContainer.value!.onmouseup = () => {
    showRubberband.value = false;
    const { top, left, width, height } = rubberbandPos.value;
    ctx.drawImage(
      canvas,
      left,
      top,
      width,
      height,
      0,
      0,
      canvas.width,
      canvas.height
    );
  };
});
</script>

<style>
#rubberbandDiv {
  position: absolute;
  border: 2px solid yellow;
  pointer-events: none;
}
</style>
